/**
 * @file   USB2XXX_LINEX_UDSTest.cpp
 * @brief  LIN UDS测试程序
 * @author wdluo(wdluo@toomoss.com)
 * @version 1.0
 * @date 2022-12-06
 * @copyright Copyright (c) 2022 重庆图莫斯电子科技有限公司
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "usb_device.h"
#include "usb2lin_ex.h"
#include "lin_uds.h"
#if _WIN32
#include <windows.h>
#pragma comment(lib,"USB2XXX.lib")
#endif

int main(int argc, const char* argv[])
{
    DEVICE_INFO DevInfo;
    int DevHandle[10];
    int LINMasterIndex = 0;
    int LINSlaveIndex = 0;
    int DevIndex = 0;
    bool state;
    int ret;
    char *MSGTypeStr[]={"UN","MW","MR","SW","SR","BK","SY","ID","DT","CK"};
    char *CKTypeStr[]={"STD","EXT","USER","NONE","ERROR"};
    //扫描查找设备，并获取设备号
    ret = USB_ScanDevice(DevHandle);
    if(ret <= 0){
        printf("No device connected!\n");
        return 0;
    }
    //打开设备
    state = USB_OpenDevice(DevHandle[DevIndex]);
    if(!state){
        printf("Open device error!\n");
        return 0;
    }

    char FunctionStr[256]={0};
    //读取设备信息
    state = DEV_GetDeviceInfo(DevHandle[DevIndex],&DevInfo,FunctionStr);
    if(!state){
        printf("Get device infomation error!\n");
        return 0;
    }else{
        printf("Firmware Info:\n");
	    printf("Firmware Name:%s\n",DevInfo.FirmwareName);
        printf("Firmware Build Date:%s\n",DevInfo.BuildDate);
        printf("Firmware Version:v%d.%d.%d\n",(DevInfo.FirmwareVersion>>24)&0xFF,(DevInfo.FirmwareVersion>>16)&0xFF,DevInfo.FirmwareVersion&0xFFFF);
        printf("Hardware Version:v%d.%d.%d\n",(DevInfo.HardwareVersion>>24)&0xFF,(DevInfo.HardwareVersion>>16)&0xFF,DevInfo.HardwareVersion&0xFFFF);
        printf("Firmware SerialNumber:%08X%08X%08X\n",DevInfo.SerialNumber[0],DevInfo.SerialNumber[1],DevInfo.SerialNumber[2]);
    }
    //初始化LIN为主机，只有主机模式才支持UDS接口函数
    ret = LIN_EX_Init(DevHandle[DevIndex],LINMasterIndex,19200,1);
    if(ret != LIN_EX_SUCCESS){
        printf("Config LIN failed!\n");
        return 0;
    }else{
        printf("Config LIN Success!\n");
    }
    LIN_UDS_ADDR UDSAddr;
    UDSAddr.CheckType = 0;
    UDSAddr.NAD = 0x01;
    UDSAddr.ReqID = 0x3C;
    UDSAddr.ResID = 0x3D;
    UDSAddr.STmin = 5;
    uint8_t reqData[]={0x01,0x02,0x03};//请求数据，一般第一字节为服务ID，后面的数据为这个服务ID携带的参数
    ret = LIN_UDS_Request(DevHandle[DevIndex],LINMasterIndex,&UDSAddr,reqData,sizeof(reqData));
    uint8_t resData[256];
    ret = LIN_UDS_Response(DevHandle[DevIndex],LINMasterIndex,&UDSAddr,resData,100);//获取响应，响应数据放到resData中，第一个字节为RSID
    LIN_EX_MSG LINMsg[1000];
    ret = LIN_UDS_GetMsgFromUDSBuffer(DevHandle[DevIndex],LINMasterIndex,LINMsg,1000);//获取前面请求和响应时的原始帧
    printf("ret = %d\n",ret);
    for(int i=0;i<ret;i++){
        printf("[%d]%s SYNC[%02X] PID[%02X] ",i,MSGTypeStr[LINMsg[i].MsgType],LINMsg[i].Sync,LINMsg[i].PID);
        for(int j=0;j<LINMsg[i].DataLen;j++){
            printf("%02X ",LINMsg[i].Data[j]);
        }
        printf("[%s][%02X] [%02d:%02d:%02d.%03d]\n",CKTypeStr[LINMsg[i].CheckType],LINMsg[i].Check,(LINMsg[i].Timestamp/3600000)%60,(LINMsg[i].Timestamp/60000)%60,(LINMsg[i].Timestamp/1000)%60,(LINMsg[i].Timestamp)%1000);
    }
    USB_CloseDevice(DevHandle[DevIndex]);
	return 0;
}

